#ifndef _BLOWFISH_H_
#define _BLOWFISH_H_

#include "mydll.h"
#include "mytypes.h"

class BlowfishStreamImpl;
class BlowfishStream
{
public:
  /// \brief This constructor is used to create an encrypted data buffer.
  ///
  /// The buffer containing the encrypted text is allocated at the same
  /// time as one insert new data with the << operator.
  BlowfishStream();

  /// \brief This constructor is used to decipher encrypted text.
  ///
  /// The data to decipher are contained into the given buffer. One should 
  /// know in advance what kind of data is expected in the buffer (we have
  /// to make use of the right '>>' operator).
  BlowfishStream(tByte *buffer, tUInt32 buffersize);

  /// \brief Destructor.
  ///
  ///
  virtual ~BlowfishStream();

  /// \brief Incremental encyphering and deciphering key setup.
  ///
  /// This function should be called at least once to setup the enciphering
  /// or deciphering key. We give the possibility to user to setup the
  /// key in several steps in order to make the reverse engineering more
  /// difficult to understand. It is recommended to call this function several
  /// times and at different locations of the code. Each time, the given key
  /// is SHA1-sumed and rehashed together with previously hashed key (from a 
  /// previous call). At each call, the memory containing the finall key is
  /// modified.
  virtual void SetKey(const tByte *key, tUInt32 keysize);

  /// \brief Finalize the key setup for ciphering or deciphering.
  ///
  /// This function finally fix the ciphering and deciphering key and 
  /// setup the final content of the key with host dependent information.
  /// Ciphering and deciphering cannot happen if this function isn't called
  /// at least once.
  virtual void FinalizeKey();

  /// \brief Returns the start of the encrypted or decrypted buffer.
  virtual tByte *Content();

  /// \brief Set the static buffer (to be decyphered).
  ///
  /// The given buffer of the given length will be used as input 
  /// for all >> operations.
  virtual void SetBuffer(tByte *buffer, tUInt32 buffersize);

  /// \brief Appends the value of the given string into the buffer.
  /// 
  /// The full content of the string will be appended. In order 
  /// delimit two consecutive strings, the '\0' character will be
  /// appended at the very end of the string.
  virtual BlowfishStream &operator <<(const string &text);

  /// \brief Pushes the value of the given 64 bits integer into the buffer.
  ///
  /// The integer value will be stored into the buffer the same way as
  /// it is in the memory. Beware of little/big endian compatibility issues.
  virtual BlowfishStream &operator <<(tUInt64 value);

  /// \brief Pushes the value of the given 32 bits integer into the buffer.
  ///
  /// The integer value will be stored into the buffer the same way as
  /// it is in the memory. Beware of little/big endian compatibility issues.
  virtual BlowfishStream &operator <<(tUInt32 value);

  /// \brief Pushes the value of the given 16 bits integer into the buffer.
  ///
  /// The integer value will be stored into the buffer the same way as
  /// it is in the memory. Beware of little/big endian compatibility issues.
  virtual BlowfishStream &operator <<(tUInt16 value);

  /// \brief Pushes the value of the given 8 bits integer into the buffer.
  ///
  /// The integer value will be stored into the buffer the same way as
  /// it is in the memory. Beware of little/big endian compatibility issues.
  virtual BlowfishStream &operator <<(tUInt8 value);

  /// \brief Extracts a string value from the buffer.
  /// 
  /// The content of the buffer will be copied into the given string
  /// until encountering the end of record ('\0'). 
  virtual BlowfishStream &operator >>(string *text);

  /// \brief Extracts a 64 bits integer value from the buffer.
  /// 
  /// The content of the buffer will be interpreted as a 64 bits integer
  /// and simply copied into the given value.
  virtual BlowfishStream &operator >>(tUInt64 *value);

  /// \brief Extracts a 32 bits integer value from the buffer.
  /// 
  /// The content of the buffer will be interpreted as a 32 bits integer
  /// and simply copied into the given value.
  virtual BlowfishStream &operator >>(tUInt32 *value);

  /// \brief Extracts a 16 bits integer value from the buffer.
  /// 
  /// The content of the buffer will be interpreted as a 16 bits integer
  /// and simply copied into the given value.
  virtual BlowfishStream &operator >>(tUInt16 *value);

  /// \brief Extracts a 8 bits integer value from the buffer.
  /// 
  /// The content of the buffer will be interpreted as a 8 bits integer
  /// and simply copied into the given value.
  virtual BlowfishStream &operator >>(tUInt8 *value);

  /// \brief Moves both the read and write pointers at an absolute location.
  ///
  /// Position parameter value should range from 0 to Size().
  virtual void Seek(tUInt32 position);

  /// \brief Empties the buffer content (size becomes 0 after this call).
  virtual void Clear();

  /// \brief Returns the current read index value.
  /// 
  /// Value range is from 0 to Size().
  virtual tUInt32 ReadIndex() const;

  /// \brief Returns the current write index value.
  ///
  /// Value range is from 0 to Size().
  virtual tUInt32 WriteIndex() const;

  /// \brief Returns the current buffer allocated size (in bytes).
  virtual tUInt32 Size() const;

  /// \brief Pad eventual uncomplete block and finish encryption/decryption
  /// 
  /// This function should be called before calling Content in case of encryption.
  /// If caller forgot to call this function, then internal buffer may contain
  /// uncomplete encrypted buffer.
  virtual void PadAndFinalize();

 private:
  BlowfishStreamImpl *_impl;

  // Copy constructor is private in order to forbid its usage
  // and in order for the compiler to not create and use the
  // default copy constructor.
  BlowfishStream(const BlowfishStream &model);

};

#endif /* _BLOWFISH_H_ */

